package com.loren.demo03.tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class TcpSocketServer {

    private static final int TCP_PORT = 9001;

    public static void main(String[] args) {
        // 定义主线程组
        EventLoopGroup parentGroup = new NioEventLoopGroup();
        // 定义从线程组
        EventLoopGroup childGroup = new NioEventLoopGroup();
        try {
            // Netty服务器的创建，ServerBootstrap 是一个启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(parentGroup, childGroup)                  // 设置主从线程组
                    .channel(NioServerSocketChannel.class)                  // 设置NIO的双向通道
                    .childOption(ChannelOption.SO_KEEPALIVE, true)    // 设置保持活动连接状态
                    .childHandler(new ChannelInitializer<SocketChannel>() { // 子处理器，用于处理childGroup
                        @Override
                        protected void initChannel(SocketChannel socketChannel) {
                            ChannelPipeline channelPipeline = socketChannel.pipeline();

                            // 加入编解码器后，处理器可以继承SimpleChannelInboundHandler<String>，这样消息类型就是字符串了
                            // channelPipeline.addLast(new StringEncoder());   // 编码器
                            // channelPipeline.addLast(new StringDecoder());   // 解码器

                            // 空闲状态事件处理器
                            channelPipeline.addLast(new IdleStateHandler(60, 1800, 1800, TimeUnit.SECONDS));

                            channelPipeline.addLast(new TcpSocketServerHandler());
                        }
                    });

            // 启动服务器并绑定端口
            ChannelFuture channelFuture = serverBootstrap.bind(TCP_PORT).sync();

            channelFuture.addListener(future -> {
                if (future.isSuccess()) {
                    System.out.println("TCP Server listening port is " + TCP_PORT);
                } else {
                    System.err.println("TCP Server listening port failed");
                }
            });

            // 对关闭通道进行监听
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            childGroup.shutdownGracefully();
            parentGroup.shutdownGracefully();
        }
    }
}
